/*
 * Header file for cda/src/main.c.
 */

#ifndef _CDA_H
#define _CDA_H

#define CHAR_STA	(0x00)
#define NUM		(0x30)
#define UPPER		(0x41)
#define LOWER		(0x61)
#define CHAR_END	(0xff)
#define CHAR_NUM	(0xff)
#define DEBUG		0
#define CHAR_USE	(0x64)
#define	FILE_NAME	(0x64)

#define CAL_AMOUNT(counter, ch_num, get_ch_fre) ({		\
	for (counter = 0; counter < CHAR_NUM; counter++) {	\
		get_ch_fre[counter].fre = 0x00000000;		\
		get_ch_fre[counter].ch = ch_num;		\
		ch_num = ch_num + 1;				\
	}							\
})

#define CAL_NUM(counter, get_ch_fre, effect_fre)					\
	do {										\
		int i;									\
		int tem = 1;								\
		for (i = 0; i < CHAR_NUM; i++) {					\
			if (0 != get_ch_fre[i].fre)					\
				counter = counter + 1;					\
		}									\
		effect_fre = (struct ch_fre *)malloc(					\
				sizeof(struct ch_fre) * (counter + 1));			\
		if (!effect_fre) {							\
			fprintf(stderr, "Allocate Error!\n");				\
			return 1;							\
		}									\
		for (i = 0; i < CHAR_NUM; i++) {					\
			if (0 != get_ch_fre[i].fre) {					\
				effect_fre[tem].fre = get_ch_fre[i].fre;		\
				effect_fre[tem].check = 0;				\
				effect_fre[tem].ch = get_ch_fre[i].ch;			\
				tem = tem + 1;						\
			}								\
		}									\
	} while (0)	

struct ch_fre {
	uint32_t fre;
	uint8_t ch;
	uint8_t check;
	uint8_t reserved[2];
};

struct huffman {
	uint32_t weight;
	uint32_t parent;
	uint32_t lchild;
	uint32_t rchild;
	uint32_t check;
	uint8_t ch;
};

struct huffcode {
	uint8_t code[CHAR_USE];
	uint8_t begin;
	uint8_t ch;
	uint8_t check;
};

struct byte {
	uint8_t bit1 : 1;
	uint8_t bit2 : 1;
	uint8_t bit3 : 1;
	uint8_t bit4 : 1;
	uint8_t bit5 : 1;
	uint8_t bit6 : 1;
	uint8_t bit7 : 1;
	uint8_t bit8 : 1;
};

int dcompress_file(char *cf);
int cal_ch_fre(char *file_name, 
		struct ch_fre *get_ch_fre);
int creat_huffman(struct huffman *huff, 
			struct ch_fre *frequency, int leaf_nodes);
int huff_select(struct huffman *huf, int temp, 
			int *get_lchild, int *get_rchild);
int creat_huffmancode(struct huffman *get_huff, struct huffcode *hc, 
				struct ch_fre *effect_fre, int counter);
int compress_file(char *file_name, char *compress_file, 
				struct ch_fre *effect_fre, struct huffcode *hc, int counter);

#endif
